package org.oa.ai;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.util.*;

public class DocxBookmarkExtractor {


//    public static void main(String[] args) throws Exception {
//        // 加载 docx 文件
//        File file = new File("D:\\桌面\\a.docx");
//        FileInputStream fis = new FileInputStream(file);
//        XWPFDocument document = new XWPFDocument(OPCPackage.open(fis));
//
//        // 提取书签信息
//        List<CTBookmark> bookmarks = new ArrayList<>();
//
//
//        for (CTP paragraph : document.getDocument().getBody().getPList()) {
//            List<CTBookmark> bookmarkStarts = paragraph.getBookmarkStartList();
//            if (bookmarkStarts != null && !bookmarkStarts.isEmpty()) {
//                bookmarks.addAll(bookmarkStarts);
//            }
//        }
//
//        for (CTBookmark bookmark : bookmarks) {
//            System.out.println("书签名称: " + bookmark.getName());
//            System.out.println("书签 ID: " + bookmark.getId());
//        }
//    }

//    public static void main(String[] args) throws Exception {
//        // 加载 docx 文件
//        File file = new File("D:\\桌面\\b.docx");
//        FileInputStream fis = new FileInputStream(file);
//        XWPFDocument document = new XWPFDocument(OPCPackage.open(fis));
//
//        // 保存所有书签信息
//        List<CTBookmark> bookmarks = new ArrayList<>();
//
//        // 存储书签名 -> 内容 的映射
//        Map<String, String> bookmarkContents = new HashMap<>();
//
//        // 当前正在处理的书签名称
//        String currentBookmarkName = null;
//
//        // 用于拼接书签内容
//        StringBuilder contentBuilder = new StringBuilder();
//
//        // 遍历段落
//        for (CTP paragraph : document.getDocument().getBody().getPList()) {
//
//            // 检查是否有书签开始
//            List<CTBookmark> starts = paragraph.getBookmarkStartList();
//            if (starts != null) {
//                for (CTBookmark start : starts) {
//                    String bookmarkName = start.getName();
//                    if (bookmarkName != null && !bookmarkName.isEmpty()) {
//                        // 开始一个新的书签
//                        if (currentBookmarkName != null) {
//                            // 如果之前有未闭合的书签，先保存
//                            bookmarkContents.put(currentBookmarkName, contentBuilder.toString());
//                            contentBuilder.setLength(0); // 清空缓存
//                        }
//                        currentBookmarkName = bookmarkName;
//                        bookmarks.add(start);
//                    }
//                }
//            }
//
//            // 如果正处于某个书签范围内，收集文本
//            if (currentBookmarkName != null) {
//                for (CTR run : paragraph.getRList()) {
//                    String text = null;
//                    if (run.getTArray() != null && run.getTArray().length > 0) {
//                        text = run.getTArray(0).getStringValue();
//                    }
//                    if (text != null && !text.isEmpty()) {
//                        contentBuilder.append(text);
//                    }
//                }
//            }
//
//            // 检查是否有书签结束
//            List<CTMarkupRange> ends = paragraph.getBookmarkEndList();
//            if (ends != null && !ends.isEmpty()) {
//                // 保存当前书签内容
//                if (currentBookmarkName != null) {
//                    bookmarkContents.put(currentBookmarkName, contentBuilder.toString());
//                    contentBuilder.setLength(0); // 清空缓存
//                    currentBookmarkName = null;
//                }
//            }
//        }
//
//        // 处理可能未闭合的最后一个书签
//        if (currentBookmarkName != null) {
//            bookmarkContents.put(currentBookmarkName, contentBuilder.toString());
//        }
//
//        // 输出结果
//        for (CTBookmark bookmark : bookmarks) {
//            String name = bookmark.getName();
//            String content = bookmarkContents.getOrDefault(name, "未找到内容");
//            System.out.println("书签名称: " + name);
//            System.out.println("书签内容: " + content);
//            System.out.println("-----------------------------");
//        }
//    }


    public static void main(String[] args) throws Exception {
        // 加载 docx 文件
        File file = new File("D:\\桌面\\b.docx");
        FileInputStream fis = new FileInputStream(file);
        XWPFDocument document = new XWPFDocument(OPCPackage.open(fis));

        // 存储书签名 -> 内容 的映射
        Map<String, StringBuilder> bookmarkContents = new HashMap<>();

        // 用于记录当前正在处理的书签栈（支持嵌套）
        Deque<CTBookmark> bookmarkStack = new LinkedList<>();

        // 遍历段落
        for (CTP paragraph : document.getDocument().getBody().getPList()) {

            // 检查是否有书签开始
            List<CTBookmark> starts = paragraph.getBookmarkStartList();
            if (starts != null) {
                for (CTBookmark start : starts) {
                    String name = start.getName();
                    if (name != null && !name.isEmpty()) {
                        // 开始一个新的书签
                        bookmarkStack.push(start);
                        bookmarkContents.putIfAbsent(name, new StringBuilder());
                    }
                }
            }

            // 检查是否有书签结束
            List<CTMarkupRange> ends = paragraph.getBookmarkEndList();
            Set<String> endedBookmarks = new HashSet<>(); // 已结束的书签
            if (ends != null && !ends.isEmpty()) {
                for (CTMarkupRange end : ends) {
                    BigInteger id = end.getId();
                    // 找到匹配的书签起始点
                    for (Iterator<CTBookmark> it = bookmarkStack.iterator(); it.hasNext();) {
                        CTBookmark bookmark = it.next();
                        if (bookmark.getId() == id) {
                            endedBookmarks.add(bookmark.getName());
                            it.remove(); // 移除栈中已结束的书签
                            break;
                        }
                    }
                }
            }

            // 收集文本：如果当前有打开的书签，则写入其内容
            if (!bookmarkStack.isEmpty()) {
                StringBuilder segment = new StringBuilder(); // 用于拼接本段内容

                for (CTR run : paragraph.getRList()) {
                    String text = null;
                    if (run.getTArray() != null && run.getTArray().length > 0) {
                        text = run.getTArray(0).getStringValue();
                    }
                    if (text != null && !text.isEmpty()) {
                        segment.append(text); // 保留原始文本中的空格
                    }
                }

                // 将整个段落的内容加上换行符，再追加到各个书签中
                if (!segment.isEmpty()) {
                    String paragraphText = segment.toString() + "\n"; // 添加段落换行
                    for (CTBookmark bookmark : bookmarkStack) {
                        bookmarkContents.get(bookmark.getName()).append(paragraphText);
                    }
                }
            }
        }

        // 处理未闭合的书签
        for (CTBookmark bookmark : bookmarkStack) {
            System.out.println("⚠️ 警告：书签 [" + bookmark.getName() + "] 未闭合");
            bookmarkContents.get(bookmark.getName()).append("（书签未闭合，内容可能不完整）");
        }

        // 输出结果
        for (Map.Entry<String, StringBuilder> entry : bookmarkContents.entrySet()) {
            System.out.println("书签名称: " + entry.getKey());
            System.out.println("书签内容: ");
            System.out.println(entry.getValue().toString());
            System.out.println("-----------------------------");
        }
    }





}
